#include "mqtt.h"
extern sqlite3 *db;
extern int flag;
extern MQTTClient client;
struct mqtt point;
/**
 * @brief 根据type==3设置周期上报时间
 *
 * @param type
 * @param period
 * @return int
 */
int set_type_period(int type, int period)
{
    char buf[2500] = {0};
    if (fileopt_readall("/home/yqj/hq_plat/res/node.json", buf) == 0)
    {
        LOGE("fileopt_readall error");
        return -1;
    }

    cJSON *tmp = cJSON_Parse(buf);
    cJSON *report = cJSON_GetObjectItem(tmp, "report");
    cJSON_DeleteItemFromObject(report, "type");
    cJSON_AddNumberToObject(report, "type", type);
    cJSON_DeleteItemFromObject(report, "period");
    cJSON_AddNumberToObject(report, "period", period);

    file_opt_write("/home/yqj/hq_plat/res/node.json", cJSON_Print(tmp), strlen(cJSON_Print(tmp)));
    cJSON_Delete(tmp);
    return 0;
}

/**
 * @brief 控制stm32还是slave
 *
 * @param js
 * @param client
 */
void do_control(cJSON *js, MQTTClient *client)
{
    cJSON *data = cJSON_GetObjectItem(js, "data");
    struct msgbuf send_buf;
    // struct msgbuf recv_buf;
    send_buf.mtype = 1;
    strcpy(send_buf.mdata, cJSON_Print(js));
    if ((cJSON_GetObjectItem(data, "key")->valueint) <= 303 && (cJSON_GetObjectItem(data, "key")->valueint) >= 301)
    {
        msg_queue_send("msg_stm32", &send_buf, sizeof(send_buf), 0);
        LOGD("send to stm32 success\n");
        // msg_queue_recv("stm32_report", &recv_buf, sizeof(recv_buf), 3, 0);
    }
    else if ((cJSON_GetObjectItem(data, "key")->valueint) <= 105)
    {
        msg_queue_send("msg_modbus", &send_buf, sizeof(send_buf), 0);
        LOGD("send to modbus success\n");
        // msg_queue_recv("msg_report", &recv_buf, sizeof(recv_buf), 2, 0);
    }
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{

    char *send = NULL;
    cJSON *root = NULL;

    cJSON *type = NULL;
   // cJSON *data = NULL;
   // cJSON *temp = NULL;
    // struct msgbuf send_buf; // 消息队列发送数组

    //int type_mode = -1;
    //int period_mod = 0;
    int result = 0; // 控制返回结果
    memset(payloadptr, 0, 256);
    // MQTTClient_message pubmsg = MQTTClient_message_initializer;
    // MQTTClient_deliveryToken token;

    strcpy(payloadptr, (char *)message->payload);
    if (!cJSON_Parse(payloadptr))
    {
        printf("data err\n");
    }
    else
    {
        LOGD("Message arrived\n");
        LOGD("     topic: %s\n", topicName);
        LOGD("   message: ");
        LOGD("recv msg = %s\n", (char *)message->payload);
    }
    root = cJSON_Parse(payloadptr);
    if (root == NULL)
    {
        LOGW("json解析失败,可能不是json字符串");
        MQTTClient_freeMessage(&message);
        MQTTClient_free(topicName);
        return -1;
    }
    /// 根据type判断
    /// 1：采集指令/采集回复指令
    /// 2：控制指令/控制回复指令
    /// 3：模式修改
    /// 4：历史数据查询
    if (strcmp(topicName, RECVDATATOPIC) == 0)
    {
        LOGD("收到数据主题");

        // 获取指令类型进行判断
        type = cJSON_GetObjectItem(root, "type");
        printf("接收到type:%d\n",type->valueint);
        if (type == NULL)
        {
            LOGW("json中type获取失败");
        }
        else if (type->valueint == 1)
        {
            LOGD("解析为数据采集指令");
            flag = 1;
        }
        else if (type->valueint == 2)
        {
            LOGD("解析为数据控制指令");
            do_control(root, (MQTTClient *)context);
            // 转成回复的json格式
            cJSON_DeleteItemFromObject(root, "data");
            // cJSON_AddNumberToObject(root, "type", 2);
            cJSON_AddNumberToObject(root, "result", result);
            if (result)
            {
                cJSON_AddStringToObject(root, "msg", "控制失败");
            }
            else
            {
                cJSON_AddStringToObject(root, "msg", "控制成功");
            }

            send = cJSON_Print(root);
            if (send == NULL)
            {
                LOGW("回复控制要发送的json获取失败");
            }
            LOGD("回复操作消息");
            mqttSend(send);
            free(send);
        }
        else if (type->valueint == 3)
        {
            LOGD("解析为模式修改指令");
            cJSON *setvalue = cJSON_GetObjectItem(root, "data");
            printf("type=%d,period=%d\n", cJSON_GetObjectItem(setvalue, "type")->valueint, cJSON_GetObjectItem(setvalue, "period")->valueint);
            set_type_period(cJSON_GetObjectItem(setvalue, "type")->valueint, cJSON_GetObjectItem(setvalue, "period")->valueint);
            // 转成回复的json格式
            cJSON_DeleteItemFromObject(root, "data");
            // cJSON *js_new = cJSON_CreateObject();
            cJSON_AddNumberToObject(root, "result", result);
            if (result)
            {
                cJSON_AddStringToObject(root, "msg", "修改失败");
            }
            else
            {
                cJSON_AddStringToObject(root, "msg", "修改成功");
            }
            send = cJSON_Print(root);
            if (send == NULL)
            {
                LOGW("回复配置指令错误");
            }
            LOGD("回复操作消息");
            mqttSend(root);
            free(send);
             cJSON_Delete(root);
        }
        else if (type->valueint == 4)
        {
            LOGD("解析为历史记录获取指令");
            history_report();
        }
        else
        {
            LOGN("非数据处理指令,重新输入");
        }
    }
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

/**
 * @brief mqtt发送函数
 *
 * @param client
 * @param str
 * @param topic
 */
void mqttSend(char *str)
{
    LOGD("发送到mqtt服务器消息");
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;

    pubmsg.qos = QOS;
    pubmsg.retained = 0;
    pubmsg.payload = str;
    pubmsg.payloadlen = (int)strlen(str);
    MQTTClient_publishMessage(client, DATATOPIC, &pubmsg, &token);
    MQTTClient_waitForCompletion(client, token, TIMEOUT);
    // LOGD("Message with delivery token %d delivered\n", token);
    LOGD("发送到mqtt服务器发送结束");
}

void delivered(void *context, MQTTClient_deliveryToken dt)
{
    LOGD("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}
void connlost(void *context, char *cause)
{
    LOGE("\nConnection lost\n");
    LOGE("     cause: %s\n", cause);
}